import jwt
from jwt import exceptions
from rest_framework.authentication import BaseAuthentication
from django.conf import settings
from rest_framework.exceptions import AuthenticationFailed


class MyJwtAuthentication(BaseAuthentication):

    def authenticate(self, request):
        token = request.query_params.get("token")
        salt = settings.SECRET_KEY
        try:
            result = jwt.decode(token, salt, True)
        except exceptions.ExpiredSignatureError:
            msg = "token失效"
            raise AuthenticationFailed({"code": 1001, "msg": msg})
        except exceptions.DecodeError:
            msg = "token认证失败"
            raise AuthenticationFailed({"code": 1002, "msg": msg})

        except exceptions.InvalidTokenError:
            msg = "非法token"
            raise AuthenticationFailed({"code": 1003, "msg": msg})

        return result, token

# 三种操作
# 1.抛出错误，后续不再执行
# 2.return一个元组，（1,2）认证通过，在视图中如果调用request.user 就是第一个值request.auth就是第二个
# 3.None不做任何操作

# import jwt
# from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
# from rest_framework.exceptions import AuthenticationFailed
# from rest_framework_jwt.authentication import jwt_decode_handler
#
#
# class MyJwtAuthentication(BaseJSONWebTokenAuthentication):
#     def authenticate(self, request):
#         # jwt_value = get_authorization_header(request)
#         jwt_value = request.META.get('HTTP_AUTHORIZATION')
#         if jwt_value:
#             try:
#                 # jwt提供了通过三段token，取出payload的方法，并且有校验功能
#                 payload = jwt_decode_handler(jwt_value)
#             except jwt.ExpiredSignature:
#                 raise AuthenticationFailed('签名过期')
#             except jwt.InvalidTokenError:
#                 raise AuthenticationFailed('用户非法')
#             except Exception as e:
#                 # 所有异常都会走到这
#                 raise AuthenticationFailed(str(e))
#             user = self.authenticate_credentials(payload)
#             return user, jwt_value
#         # 没有值，直接抛异常
#         raise AuthenticationFailed('您没有携带认证信息')
